package com.honor.games.wg.services;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.google.common.base.Preconditions.*;

import com.google.common.eventbus.EventBus;
import com.honor.games.wg.entities.EntityType;
import com.honor.games.wg.entities.SelectedEntity;
import com.honor.games.wg.entities.WGTile;
import com.honor.games.wg.entities.WGUnit;
import com.honor.games.wg.events.UnitMoveCommandEvent;

@Service
public class WGSelectorServices {

	private static Logger logger = LoggerFactory.getLogger(WGSelectorServices.class);

	@Autowired
	private EventBus eventBus;
	
	@Autowired
	private WGWorldServices worldServices;

	@Autowired
	private WGGraphicsServices graphicsServices;

	private Queue<SelectedEntity> selectionHistory = new ArrayBlockingQueue<SelectedEntity>(10);

	public void selectUnit(WGUnit unit) {
		checkNotNull(unit);

		logger.trace("Select unit - START");

		if (unit.isSelected()) {
			unit.setSelected(false);
			logger.trace("Unit " + unit.getUnitType() + " is deselected");
			clearSelectionHistory();
		} else {
			unit.setSelected(true);
			logger.trace("Unit " + unit.getUnitType() + " is selected");
			SelectedEntity selectedEntity = new SelectedEntity(EntityType.UNIT, unit);
			addSelectionToHistory(selectedEntity);
		}
		logger.trace("Select unit - STOP");
	}

	private synchronized void addSelectionToHistory(SelectedEntity selectedEntity) {
		checkNotNull(selectedEntity);
		
		if(!selectionHistory.isEmpty()) { 
			if(selectionHistory.peek().getEntityType() == EntityType.UNIT) {
				
				if(selectedEntity.getEntityType() == EntityType.TILE) {
					WGUnit unit = (WGUnit) selectionHistory.peek().getEntity();
					WGTile tile = (WGTile) selectedEntity.getEntity();
					eventBus.post(new UnitMoveCommandEvent(unit, tile));
				}
			}

			clearSelectionHistory();
		} else {
			selectionHistory.add(selectedEntity);
		}
	}

	private synchronized void clearSelectionHistory() {
		selectionHistory.clear();
	}

	public void selectTile(WGTile tileClicked) {
		checkNotNull(tileClicked);

		logger.trace("Select tile - START");
		if (worldServices.getBoard().getSelectedTile() != null && worldServices.getBoard().getSelectedTile().getId() == tileClicked.getId()) {
			worldServices.getBoard().unselect();
			graphicsServices.unselectTile();
			clearSelectionHistory();
		} else {
			worldServices.getBoard().setTileSelected(tileClicked.getLocationX(), tileClicked.getLocationY());
			graphicsServices.selectTile(tileClicked.getLocationX(), tileClicked.getLocationY());
			addSelectionToHistory(new SelectedEntity(EntityType.TILE, tileClicked));
		}
		logger.trace("Select tile - STOP");
	}
}
